#!/bin/python
# -*- coding: utf8 -*-


from lib.common.aliyun_ots import cli, Condition, INF_MIN, INF_MAX
import lib.common.func as com_func
import lib.common.aliyun_redis

ots = cli()
redis = lib.common.aliyun_redis.cli()

TABLE = '${table_name}'
TABLE_CACHE = '${table_name}_cache'
TABLE_LIST_CACHE = '${table_name}_list_cache'


def add_${table_name}(${key_first}, ${key_second}, attr={}):
    ts = lib.common.func.get_ts()
    pk = {
        '${key_first}': ${type_first}(${key_first}),
        '${key_second}': ${type_second}(${key_second}),
    }
    attr['ctime'] = ts
    attr['mtime'] = ts
    code = ots.put_row(TABLE, Condition('EXPECT_NOT_EXIST'), pk, attr)
    if code == 0:
        clear_${table_name}_list_cache(${key_first})
    return code


def update_${table_name}(${key_first}, ${key_second}, attr={}):
    ts = lib.common.func.get_ts()
    pk = {
        '${key_first}': ${type_first}(${key_first}),
        '${key_second}': ${type_second}(${key_second}),
    }
    attr['mtime'] = ts
    code = ots.update_row(TABLE, Condition('EXPECT_EXIST'), pk, {'put': attr})
    if code == 0:
        clear_${table_name}_list_cache(${key_first})
        clear_${table_name}_cache(${key_first}, ${key_second})
    return code


def delete_${table_name}(${key_first}, ${key_second}):
    pk = {
        '${key_first}': ${type_first}(${key_first}),
        '${key_second}': ${type_second}(${key_second}),
    }
    code = ots.delete_row(TABLE, Condition('IGNORE'), pk)
    if code == 0:
        clear_${table_name}_list_cache(${key_first})
        clear_${table_name}_cache(${key_first}, ${key_second})
    return code


def get_${table_name}(${key_first}, ${key_second}):
    data = get_${table_name}_cache(${key_first}, ${key_second})
    if data is None:
        data = get_${table_name}_ots(${key_first}, ${key_second})
        if len(data) > 0:
            set_${table_name}_cache(${key_first}, ${key_second}, data)
    else:
        data = lib.common.func.deserialize(data)
    return data


def get_${table_name}_ots(${key_first}, ${key_second}):
    pk = {
        '${key_first}': ${type_first}(${key_first}),
        '${key_second}': ${type_second}(${key_second}),
    }
    data = ots.get_row(TABLE, pk, [])
    return data


def get_${table_name}_list(${key_first}):
    data_list = get_${table_name}_list_cache(${key_first})
    if data_list is None:
        data_list = get_${table_name}_list_ots(${key_first})
        if len(data_list) > 0:
            set_${table_name}_list_cache(${key_first}, data_list)
    else:
        data_list = lib.common.func.deserialize(data_list)

    return data_list


def get_${table_name}_list_ots(${key_first}):
    pk_b = {
        '${key_first}': ${type_first}(${key_first}),
        '${key_second}': INF_MIN
    }
    pk_e = {
        '${key_first}': ${type_first}(${key_first}),
        '${key_second}': INF_MAX
    }
    data_list = []
    while pk_b is not None:
        rows, pk_b = ots.get_range(TABLE, 'FORWARD', pk_b, pk_e, [])
        if len(rows) > 0:
            data_list.extend(rows)
    return data_list


def get_all_${table_name}_list():
    pk_b = {
        '${key_first}': INF_MIN,
        '${key_second}': INF_MIN
    }
    pk_e = {
        '${key_first}': INF_MAX,
        '${key_second}': INF_MAX
    }
    data_list = []
    while pk_b is not None:
        rows, pk_b = ots.get_range(TABLE, 'FORWARD', pk_b, pk_e, [])
        if len(rows) > 0:
            data_list.extend(rows)
    return data_list


def set_${table_name}_cache(${key_first}, ${key_second}, data):
    redis.set('{}-{}-{}'.format(TABLE_CACHE, ${key_first}, ${key_second}), lib.common.func.serialize(data))


def get_${table_name}_cache(${key_first}, ${key_second}):
    return redis.get('{}-{}-{}'.format(TABLE_CACHE, ${key_first}, ${key_second}))


def clear_${table_name}_cache(${key_first}, ${key_second}):
    redis.delete('{}-{}-{}'.format(TABLE_CACHE, ${key_first}, ${key_second}))


def set_${table_name}_list_cache(${key_first}, data):
    redis.set('{}-{}'.format(TABLE_LIST_CACHE, ${key_first}), lib.common.func.serialize(data))


def get_${table_name}_list_cache(${key_first}):
    return redis.get('{}-{}'.format(TABLE_LIST_CACHE, ${key_first}))


def clear_${table_name}_list_cache(${key_first}):
    redis.delete('{}-{}'.format(TABLE_LIST_CACHE, ${key_first}))
